import axios from 'axios'
import router from '@/router'

const API_URL = '/api'

// 安全地从sessionStorage获取用户数据
const getSafeUserFromStorage = () => {
  try {
    const userJson = sessionStorage.getItem('user');
    if (!userJson) return null;
    
    const user = JSON.parse(userJson);
    // 验证用户对象必须包含id和username字段
    if (!user || !user.id || !user.username) {
      console.error('sessionStorage中的用户数据不完整，重置用户状态');
      sessionStorage.removeItem('user');
      return null;
    }
    return user;
  } catch (error) {
    console.error('从sessionStorage解析用户数据失败:', error);
    sessionStorage.removeItem('user');
    return null;
  }
};

// 安全地从sessionStorage获取token
const getSafeTokenFromStorage = () => {
  const token = sessionStorage.getItem('token');
  return token;
};

// 初始状态，尝试从sessionStorage恢复登录状态
const state = {
  token: getSafeTokenFromStorage(),
  user: getSafeUserFromStorage(),
  authError: null
};

const mutations = {
  AUTH_SUCCESS(state, { token, user }) {
    state.token = token
    state.user = user
  },
  AUTH_ERROR(state) {
    state.token = ''
    state.user = null
  },
  LOGOUT(state) {
    state.token = ''
    state.user = null
  },
  UPDATE_USER(state, user) {
    state.user = user
  },
  SET_AUTH_ERROR(state, error) {
    state.authError = error
  },
  SET_TOKEN(state, token) {
    state.token = token
  },
  SET_USER(state, user) {
    state.user = user
  }
}

const actions = {
  // 注册用户
  async register({ commit, dispatch }, userData) {
    try {
      dispatch('setLoading', true, { root: true })
      
      // Clear any previous errors
      dispatch('setError', null, { root: true })
      
      // Validate required fields on client side before sending request
      const requiredFields = ['username', 'email', 'password', 'full_name']
      const missingFields = []
      
      requiredFields.forEach(field => {
        if (!userData[field]) {
          missingFields.push(field)
        }
      })
      
      if (missingFields.length > 0) {
        const errorMsg = `缺少必填字段: ${missingFields.join(', ')}`
        console.error('Registration validation failed:', errorMsg)
        dispatch('setError', errorMsg, { root: true })
        return false
      }
      
      console.log('Starting registration with data:', {
        username: userData.username,
        email: userData.email,
        full_name: userData.full_name,
        has_phone: !!userData.phone,
        has_address: !!userData.address,
        password_length: userData.password ? userData.password.length : 0
      })
      
      const response = await axios.post(`${API_URL}/auth/register`, userData)
      
      if (!response.data || !response.data.token) {
        console.error('Registration failed: Invalid response from server')
        dispatch('setError', '注册失败：服务器响应无效', { root: true })
        return false
      }
      
      const token = response.data.token
      
      // 确保token已设置到sessionStorage
      sessionStorage.setItem('token', token)
      
      // 更新认证状态
      commit('AUTH_SUCCESS', { token, user: null })
      
      // 获取用户数据
      try {
        const user = await dispatch('getUserData', token)
        // 确保成功获取了用户数据
        if (!user || !user.id) {
          throw new Error('无法获取用户数据')
        }
        
        // 将用户对象存储到sessionStorage
        sessionStorage.setItem('user', JSON.stringify(user))
        
        // 更新状态
        commit('AUTH_SUCCESS', { token, user })
        
        console.log('Registration completed successfully')
        dispatch('setLoading', false, { root: true })
        return true
      } catch (userDataError) {
        console.error('Failed to get user data after registration:', userDataError)
        
        // 尝试备用方法
        try {
          const fallbackUser = await dispatch('getUserDataFallback', token)
          if (fallbackUser && fallbackUser.id) {
            sessionStorage.setItem('user', JSON.stringify(fallbackUser))
            commit('AUTH_SUCCESS', { token, user: fallbackUser })
            dispatch('setLoading', false, { root: true })
            return true
          }
        } catch (fallbackError) {
          console.error('Fallback method also failed:', fallbackError)
        }
        
        // 如果所有获取用户数据的尝试都失败，但令牌有效，返回部分成功
        dispatch('setLoading', false, { root: true })
        dispatch('setError', '已注册但无法获取完整用户信息，请重新登录', { root: true })
        return false
      }
    } catch (error) {
      console.error('Registration error:', error)
      const errorMessage = error.response?.data?.message || error.message || '注册失败'
      dispatch('setError', errorMessage, { root: true })
      dispatch('setLoading', false, { root: true })
      return false
    }
  },
  
  // 登录用户
  async login({ commit, dispatch }, payload) {
    try {
      dispatch('setLoading', true, { root: true })
      
      // 清除之前的错误
      commit('SET_AUTH_ERROR', null)
      
      // 发送登录请求
      console.log('发送登录请求:', payload)
      
      try {
        const response = await axios.post(`${API_URL}/auth/login`, payload)
        console.log('登录响应:', response.data)
        
        if (response.data && response.data.token) {
          const token = response.data.token
          
          // 存储token
          sessionStorage.setItem('token', token)
          commit('SET_TOKEN', token)
          
          try {
            // 获取用户信息 - 尝试先用me端点
            console.log("尝试获取用户信息，使用/me端点")
            const userResponse = await axios.get(`${API_URL}/auth/me`, { 
              headers: { 'x-auth-token': token }
            })
            
            // 检查并存储用户信息
            if (userResponse.data) {
              console.log('用户数据:', userResponse.data)
              sessionStorage.setItem('user', JSON.stringify(userResponse.data))
              commit('SET_USER', userResponse.data)
            }
          } catch (meError) {
            console.error("使用/me端点获取用户信息失败，尝试/user端点", meError)
            try {
              // 尝试使用user端点
              const userResponse = await axios.get(`${API_URL}/auth/user`, { 
                headers: { 'x-auth-token': token }
              })
              
              if (userResponse.data) {
                console.log('用户数据(从/user端点):', userResponse.data)
                sessionStorage.setItem('user', JSON.stringify(userResponse.data))
                commit('SET_USER', userResponse.data)
              }
            } catch (userError) {
              console.error("两个用户信息端点都失败了", userError)
              throw new Error("无法获取用户信息")
            }
          }
          
          // 登录成功后，跳转到之前尝试访问的页面或首页
          const redirect = router.currentRoute.value.query.redirect || '/'
          router.push(redirect)
          
          return true
        } else {
          throw new Error('无效的响应数据')
        }
      } catch (requestError) {
        console.error('登录请求失败:', requestError)
        
        let errorMessage = '登录失败，请检查您的用户名和密码'
        if (requestError.response) {
          // 处理服务器返回的错误
          errorMessage = requestError.response.data?.message || errorMessage
        } else if (requestError.request) {
          // 请求已发送但未收到响应
          errorMessage = '服务器无响应，请检查网络连接或服务器状态'
        } else {
          // 请求设置错误
          errorMessage = requestError.message || '发送请求时出错'
        }
        
        commit('SET_AUTH_ERROR', errorMessage)
        dispatch('setError', errorMessage, { root: true })
        return false
      }
    } catch (error) {
      console.error('登录失败:', error)
      
      let errorMessage = '登录失败，请检查您的用户名和密码'
      if (error.response) {
        errorMessage = error.response.data?.message || errorMessage
      }
      
      commit('SET_AUTH_ERROR', errorMessage)
      dispatch('setError', errorMessage, { root: true })
      return false
    } finally {
      dispatch('setLoading', false, { root: true })
    }
  },
  
  // 获取用户数据
  async getUserData({ commit }, token) {
    try {
      console.log('正在获取用户数据...');
      // 确保我们有有效的令牌
      if (!token) {
        console.error('令牌无效，无法获取用户数据');
        throw new Error('无效的认证令牌');
      }
      
      // 同时使用两种格式的认证头
      const config = { 
        headers: { 
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token 
        } 
      };
      
      console.log('使用的认证头:', {
        authHeader: `Bearer ${token.substring(0, 10)}...`,
        tokenHeader: `${token.substring(0, 10)}...`,
        tokenLength: token.length
      });
      
      const response = await axios.get(`${API_URL}/auth/user`, config);
      console.log('获取到的用户数据:', response.data);
      
      // 确保我们收到有效的用户数据
      if (!response.data || typeof response.data !== 'object') {
        console.error('服务器返回的用户数据无效:', response.data);
        throw new Error('服务器返回的用户数据无效');
      }
      
      const user = response.data;
      
      // 额外检查用户对象是否包含必要字段
      if (!user.id || !user.username) {
        console.error('用户数据缺少必要字段:', user);
        throw new Error('用户数据格式不完整');
      }
      
      // 存储token和用户信息
      sessionStorage.setItem('token', token);
      sessionStorage.setItem('user', JSON.stringify(user));
      
      // 标记认证成功
      commit('AUTH_SUCCESS', { token, user });
      
      // 返回用户信息
      return user;
    } catch (error) {
      console.error('获取用户数据失败:', error.message);
      throw error;
    }
  },
  
  async getUserDataFallback({ commit }, token) {
    try {
      console.log('尝试使用备用方法获取用户数据');
      
      if (!token) {
        console.error('缺少有效令牌，无法使用备用方法');
        throw new Error('备用方法需要有效的令牌');
      }
      
      // 创建备用请求配置，指定完整的URL
      const config = {
        headers: {
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token
        }
      };
      
      console.log('备用方法使用的认证头:', {
        authHeaderPreview: `Bearer ${token.substring(0, 10)}...`,
        tokenHeaderPreview: `${token.substring(0, 10)}...`
      });
      
      // 尝试使用通用端点获取用户资料
      const response = await axios.get(`${API_URL}/users/profile`, config);
      
      console.log('备用方法返回数据:', response.data);
      
      if (!response.data || !response.data.id || !response.data.username) {
        console.error('备用方法返回的用户数据无效:', response.data);
        throw new Error('无法验证用户身份');
      }
      
      const user = response.data;
      
      // 存储令牌和用户数据
      sessionStorage.setItem('token', token);
      sessionStorage.setItem('user', JSON.stringify(user));
      
      commit('AUTH_SUCCESS', { token, user });
      return user;
    } catch (error) {
      console.error('备用方法获取用户数据失败:', error.message);
      commit('AUTH_ERROR');
      sessionStorage.removeItem('token');
      sessionStorage.removeItem('user');
      throw error;
    }
  },
  
  // 登出用户
  logout({ commit }) {
    commit('LOGOUT')
    sessionStorage.removeItem('token')
    sessionStorage.removeItem('user')
    router.push('/')
  },
  
  // 更新用户资料
  async updateProfile({ commit, dispatch, getters }, userData) {
    try {
      dispatch('setLoading', true, { root: true })
      
      // 获取当前令牌
      const token = getters.token
      if (!token) {
        throw new Error('需要登录才能更新个人资料')
      }
      
      // 设置请求头
      const config = {
        headers: {
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token
        }
      }
      
      // 更新用户资料
      const response = await axios.put(`${API_URL}/users/profile`, userData, config)
      
      if (!response.data) {
        throw new Error('服务器响应无效')
      }
      
      const updatedUser = response.data
      
      // 更新状态和存储
      commit('UPDATE_USER', updatedUser)
      sessionStorage.setItem('user', JSON.stringify(updatedUser))
      
      dispatch('setLoading', false, { root: true })
      return updatedUser
    } catch (error) {
      console.error('更新资料失败:', error)
      let errorMessage = '更新个人资料失败'
      
      if (error.response) {
        errorMessage = error.response.data?.message || '服务器错误'
      } else if (error.message) {
        errorMessage = error.message
      }
      
      dispatch('setError', errorMessage, { root: true })
      dispatch('setLoading', false, { root: true })
      throw error
    }
  },
  
  // 刷新认证状态
  async refreshAuthState({ commit, dispatch }) {
    try {
      console.log('刷新认证状态...')
      // 检查sessionStorage的令牌
      const token = sessionStorage.getItem('token')
      if (!token) {
        console.log('本地不存在令牌，认证状态为：未登录')
        commit('AUTH_ERROR')
        return false
      }
      
      console.log('本地存在令牌，尝试获取用户数据')
      try {
        // 尝试获取用户数据来验证令牌有效性
        const user = await dispatch('getUserData', token)
        console.log('令牌有效，用户已刷新:', user.username)
        return true
      } catch (error) {
        console.error('令牌可能已过期，尝试备用方法:', error.message)
        try {
          // 尝试备用方法
          const fallbackUser = await dispatch('getUserDataFallback', token)
          console.log('使用备用方法验证成功:', fallbackUser.username)
          return true
        } catch (fallbackError) {
          // 如果两种方法都失败，说明令牌无效
          console.error('认证刷新失败，令牌无效:', fallbackError.message)
          commit('AUTH_ERROR')
          sessionStorage.removeItem('token')
          sessionStorage.removeItem('user')
          return false
        }
      }
    } catch (error) {
      console.error('刷新认证状态时出错:', error)
      commit('AUTH_ERROR')
      return false
    }
  }
}

const getters = {
  isAuthenticated: state => !!state.token,
  isAdmin: state => state.user && (state.user.is_admin === true || state.user.is_admin === 1),
  currentUser: state => state.user,
  token: state => state.token,
  authError: state => state.authError
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
} 